Data Overview
import_data("jake_gyllenhaal")
filmes <- read_imported_data()
filmes %>%
glimpse()
Observations: 20
Variables: 5
$ avaliacao <int> 92, 68, 73, 52, 73, 59, 82, 85, 92, 49, 35, 64, 47, 90, 87, 61, 62, 44, ...
$ filme <chr> "Stronger", "Life", "Nocturnal Animals", "Demolition", "Everest", "South...
$ papel <chr> "Jeff Bauman", "David Jordan", "Tony HastingsEdward Sheffield", "Davis M...
$ bilheteria <dbl> 4.2, 30.2, 10.7, 1.7, 46.6, 42.4, 61.0, 39.1, 54.7, 33.3, 90.8, 28.6, 9....
$ ano <int> 2017, 2017, 2016, 2016, 2015, 2015, 2013, 2012, 2011, 2010, 2010, 2009, ...
Bilheteria
- Dados de bilheteria se referem ao arrecadamento dentro dos Estados Unidos.
p <- filmes %>%
ggplot(aes(x = ano,
y = bilheteria,
text = paste("Filme:",filme,
"\nBilheteria:",
bilheteria,"m",
"\nAno:",ano))) +
geom_point(size = 4, color = paleta[1]) +
labs(y = "Bilheteria", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
layout(autosize = F)
Entre os filmes em que Jake atuou um foge aos outros em termos de faturamento, o filme “The Day After Tomorrow” lançado em 2004.
É possível perceber uma tendência de queda no faturamento dos filmes em que Jake atuou após 2013.
filmes %>%
ggplot(aes(x = bilheteria)) +
geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0,
fill = "grey", color = "black") +
geom_rug(size = .5) +
scale_x_continuous(breaks=seq(0,200,20)) +
labs(y = "Frequência Relativa", x = "Bilheteria")

Vemos claramente a disparidade entre “The Day After Tomorrow” e os outros filmes.
Nenhum valor fora do domínio de valores esperado, e.g. valores negativos.
p <- filmes %>%
ggplot(aes(x = "",
y = bilheteria,
label = filme,
text = paste("Filme:",filme,
"\nBilheteria:",
bilheteria,"m"))) +
geom_jitter(width = .05, alpha = .3, size = 3) +
labs(x = "", y="Bilheteria")
ggplotly(p, tooltip="text") %>%
layout(autosize = F)
Avaliação
p <- filmes %>%
ggplot(aes(x = ano,
y = avaliacao,
text = paste("Filme:",filme,
"\nAvaliação:",
avaliacao,
"\nAno:",ano))) +
geom_point(size = 4, color = paleta[1]) +
scale_y_continuous(limits = c(0, 100)) +
labs(y = "Avaliação RT", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
layout(autosize = F)
- Entre 2005 e 2010 Jake participou de uma série de filmes em particular que não agradou os críticos
- Não aparenta haver uma tendência particularmente clara em razão do ano de lançamento.
filmes %>%
ggplot(aes(x = avaliacao)) +
geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0,
fill = paleta[3], color = "black") +
geom_rug(size = .5) +
scale_x_continuous(breaks=seq(0,100,10)) +
labs(y = "Frequência Relativa", x = "Avaliação RT")

É possível perceber uma quantidade considerável de filmes com notas acima de 80.
Nenhum valor fora do domínio de valores esperado, e.g. valores negativos.
p <- filmes %>%
ggplot(aes(x = "",
y = avaliacao,
text = paste(
"Filme:",filme,
"\nAvaliação:",avaliacao))) +
geom_jitter(width = .05, alpha = .3, size = 3) +
labs(x = "", y="Avaliação RT")
ggplotly(p, tooltip = "text") %>%
layout(autosize = F)
- Intuitivamente três grupos surgem:
- Os filmes com avaliação acima de 80
- Os filmes com avaliação entre 55 e 70
- Os filmes com avaliação abaixo de 55
Agrupamento hierárquico
Uma dimensão
Bilheteria
agrupamento_h = filmes %>%
mutate(nome = paste0(filme, " (bil=", bilheteria, ")")) %>%
as.data.frame() %>%
column_to_rownames("filme") %>%
select(bilheteria) %>%
dist(method = "euclidian") %>%
hclust(method = "centroid")
ggdendrogram(agrupamento_h, rotate = T, size = 2, theme_dendro = F) +
labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
geom_hline(aes(yintercept = c(20,30), color=c("4 grupos","3 grupos"))) +
scale_colour_manual(name="#Grupos",
values=c("#56B4E9", "#FF9999"))

- Em termos de Dendograma a divisão em quatro grupos assim como a divisão em 3 grupos parecem ser apropriadas, dado que o aumento de dissimilaridade de 4 para 3 grupos não aparentar ser substancial.
- Corte feito para 4 grupos
atribuicoes = get_grupos(agrupamento_h, num_grupos = 1:6)
atribuicoes = atribuicoes %>%
left_join(filmes, by = c("label" = "filme"))
atribuicoes %>%
ggplot(aes(x = "Filmes", y = bilheteria, colour = grupo)) +
geom_jitter(width = .02, height = 0, size = 1.6, alpha = .6) +
facet_wrap(~ paste(k, " grupos")) +
scale_color_brewer(palette = "Dark2") +
labs(y = "Bilheteria (milhões)", x = "", title = "Agrupamento por Bilheteria")

- A divisão em 4 grupos parece ser mais apropriada que a divisão em 3 grupos.
- O cluster de filmes na base do gráfico aparenta exigir um grupo próprio (Na divisão em 4 grupos o grupo mencionado seria o grupo 1).
k_escolhido = 4
m <- list(l = 220)
p <-atribuicoes %>%
filter(k == k_escolhido) %>%
ggplot(aes(x = reorder(label, bilheteria),
y = bilheteria,
colour = grupo,
text = paste(
"Filme:", reorder(label, bilheteria),
"\nAvaliação:", bilheteria,
"\nGrupo:", grupo))) +
geom_jitter(width = .02, height = 0, size = 3, alpha = .6) +
facet_wrap(~ paste(k, " grupos")) +
scale_color_brewer(palette = "Dark2") +
labs(x = "", y = "Avaliação RT") +
coord_flip()
ggplotly(p,tooltip = "text") %>%
layout(autosize = F, margin = m)
- The Day After Tomorrow exigiu um grupo para si, como era esperado.
Avaliação
agrupamento_h = filmes %>%
mutate(nome = paste0(filme, " (av=", avaliacao, ")")) %>%
as.data.frame() %>%
column_to_rownames("filme") %>%
select(avaliacao) %>%
dist(method = "euclidian") %>%
hclust(method = "ward.D")
ggdendrogram(agrupamento_h, rotate = T, size = 2, theme_dendro = F) +
labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
geom_hline(aes(yintercept = 30),color="red")

- Em termos de Dendograma a divisão em três grupos parece ser a mais apropriada, dado que o aumento da dissimilaridade passa a ser substancial quando passamos de 3 para 2 grupos.
atribuicoes = get_grupos(agrupamento_h, num_grupos = 1:6)
atribuicoes = atribuicoes %>%
left_join(filmes, by = c("label" = "filme"))
atribuicoes %>%
ggplot(aes(x = "Filmes", y = avaliacao, colour = grupo)) +
geom_jitter(width = .02, height = 0, size = 1.6, alpha = .6) +
facet_wrap(~ paste(k, " grupos")) +
scale_color_brewer(palette = "Dark2") +
labs(y = "Avaliação RT", x = "", title = "Agrupamento por Avaliação")

- Visualmente a divisão em três grupos parece de fato ser apropriada, o que está em acordo com o dendrograma.
k_escolhido = 3
m <- list(l = 220)
p <-atribuicoes %>%
filter(k == k_escolhido) %>%
ggplot(aes(x = reorder(label, avaliacao),
y = avaliacao,
colour = grupo,
text = paste(
"Filme:", reorder(label, avaliacao),
"\nAvaliação:", avaliacao,
"\nGrupo:", grupo))) +
geom_jitter(width = .02, height = 0, size = 3, alpha = .6) +
facet_wrap(~ paste(k, " grupos")) +
scale_color_brewer(palette = "Dark2") +
labs(x = "", y = "Avaliação RT") +
coord_flip()
ggplotly(p,tooltip = "text") %>%
layout(autosize = F, margin = m)
- Discutivelmente, Prince of Persia: The Sands of Time poderia exigir um grupo para si próprio.
Duas dimensões
agrupamento_h_2d = filmes %>%
mutate(bilheteria = log10(bilheteria)) %>%
mutate_at(vars("avaliacao", "bilheteria"), funs(scale)) %>%
column_to_rownames("filme") %>%
select("avaliacao", "bilheteria") %>%
dist(method = "euclidean") %>%
hclust(method = "ward.D")
ggdendrogram(agrupamento_h_2d, rotate = TRUE, theme_dendro = F) +
labs(y = "Dissimilaridade", x = "", title = "Dendrograma") +
geom_hline(aes(yintercept = 4),color="red")

- Passar de 4 para 3 grupos representa pouca variação em termos de dissimilaridade
- Passar de 3 para 2 grupos apresenta um aumento relativo de dissimilaridade substancial, portanto 3 ou 4 grupos parece ser uma boa escolha.
filmes2 <- filmes %>%
mutate(bilheteria = log10(bilheteria))
plota_hclusts_2d(agrupamento_h_2d,
filmes2,
c("avaliacao", "bilheteria"),
linkage_method = "ward.D",
ks = 1:6,
palette = "Dark2") +
scale_y_log10() +
labs(y = "Bilheteria", x = "Avaliação", title = "Agrupamento com Duas Dimensões")

- A escolha por 4 grupos parece ser apropriada, por refletir tanto questões de bilheteria como de avaliação. Em acordo com o que interpretamos no dendrograma optaremos por 4 grupos.
atribuicoes = get_grupos(agrupamento_h_2d, num_grupos = 1:6)
atribuicoes = atribuicoes %>%
filter(k == 4) %>%
mutate(filme = label) %>%
left_join(filmes, by = "filme")
p <- atribuicoes %>%
ggplot(aes(x = avaliacao,
y = bilheteria,
colour = grupo,
text = paste(
"Filme:", filme,
"\nBilheteria:", bilheteria,"m\n",
"Avaliação:", avaliacao))) +
geom_jitter(width = .02, height = 0, size = 3, alpha = .6) +
facet_wrap(~ paste(k, " grupos")) +
scale_color_brewer(palette = "Dark2") +
scale_y_log10() +
labs(y = "Bilheteria", x = "Avaliação RT")
ggplotly(p, tooltip = "text") %>%
layout(autosize = F)
- \(\color{green}{\text{Grupo 1 (Oddball):}}\) Filmes em geral bem recebidos pela crítica porém mal recebidos pelo público, o que se reflete no seu baixo arrecadamento.
- Stronger: Filme biográfico sobre ‘Jeff Bauman’, vítima do atentado de Boston que perdeu ambas as pernas na explosão. O filme foi muito bem recebido pelos críticos que o elogiaram por ser bem executado, comovente e por focar numa história de superação ao invés de usar a tragédia para alimentar a paranóia em cima do terrorismo. O filme porém foi um fracasso em termos de bilheteria.
- \(\color{#CF5300}{\text{Grupo 2 (Sessão da Tarde):}}\) Filmes em geral não tão bem recebidos pela crítica e mais formulaicos. Em termos de bilheteria a maior parte deles foi baixa mas o filme se pagou, com duas exceções que arrecadaram melhor (‘Prince of Persia: The Sands of Time’ e ‘The Day After Tomorrow’). Para esse grupo existe uma curiosidade, para a maioria dos filmes desse grupo quanto maior o arrecadamento menor a avaliação.
- Prince of Persia: The Sands of Time: Baseado no jogo de mesmo nome, este jogo uma referência em qualidade e inovação. O filme resultou em comentários decepcionados tanto de críticos e fãs que não falharam em contribuir pro arrecadamento do filme.
- \(\color{purple}{\text{Grupo 3 (Demolition of a budget):}}\) Filmes em geral mal recebidos pela crítica e pelo público, o que se reflete no seu baixo arrecadamento e avaliações.
- Demolition: Neste filme Jake atua no papel de um homem que volta ao trabalho depois de perder a esposa e encontra contato humano em uma atendente de telemarketing ao reclamar de uma vending machine. O filme foi um fracasso em termos de arrecadamento assim como em termos de crítica. O filme teve seu script apontado como grande problema, esse foi descrito como ‘tentando afetar profundidade’ e anti-carismático.
- \(\color{magenta}{\text{Grupo 4 (Brokeback Mountain):}}\) Filmes aclamados pela crítica e de faturamento decente ou de sucesso, os filmes dese grupo são de tom mais sério tratando de assuntos significativos e geradores de controvérsia (assassinatos em série verídicos, não heterossexualidade, terrorismo.. ).
- Brokeback Mountain: Provavelmente a melhor atuação de Jake Gyllenhaal até o momento, esse filme rendeu a Jake uma indicação ao Oscar e levantou muita controvérsia por conter uma cena de sexo entre pessoas do mesmo sexo. A Academia (responsável por escolher os vencedores do Oscar) foi acusada de homofobia por não escolher esse filme como o ganhador de Melhor Fotografia, ainda assim Brokeback Mountain ganhou mais ganhou 141 prêmios e 128 nominações de acordo com o IMDB. O filme foi considerado um sucesso tanto em faturamento como em avaliação.
LS0tCnRpdGxlOiAiVGlwb3MgZGUgZmlsbWUgZGUgSmFrZSBHeWxsZW5oYWFsIgphdXRob3I6ICJKb3PDqSBCZW5hcmRpIGRlIFNvdXphIE51bmVzIgpkYXRlOiAiMjIvMDUvMjAxOCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgo8YnIvPjxici8+CgojIEludHJvZHXDp8OjbwoKPiBBbsOhbGlzZSBleHBsb3JhdMOzcmlhIGRlIGRhZG9zIGRvIFtSb3R0ZW5Ub21hdG9lc10oaHR0cHM6Ly93d3cucm90dGVudG9tYXRvZXMuY29tLykgc29icmUgbyBhdG9yIEpha2UgR3lsbGVuaGFhbC4gTyBjw7NkaWdvIGVtcHJlZ2FkbyBuYSBleHRyYcOnw6NvIGRvcyBkYWRvcyBhcXVpIGFuYWxpemFkb3MgZSBhIGRlc2NyacOnw6NvIGRlIGNvbW8gbyB1c2FyIGVuY29udHJhLXNlIG5vICBbcmVwb3NpdMOzcmlvIG9yaWdlbV0oaHR0cHM6Ly9naXRodWIuY29tL0JlbmFyZGkvYWdydXBhbWVudG8tZmlsbWVzLykgZGVzdGUgcmVsYXTDs3Jpby4KCiogRW50cmFkYXMgcXVlIG7Do28gY29udMOqbSBkYWRvcyBzb2JyZSBiaWxoZXRlcmlhIGZvcmFtIGlnbm9yYWRhcy4KCjxicj4KCioqKgoKPGJyPgoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoaGVyZSkKbGlicmFyeShjbHVzdGVyKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZ2RlbmRybykKCnNvdXJjZShoZXJlOjpoZXJlKCJjb2RlL2xpYi5SIikpCnNvdXJjZShoZXJlOjpoZXJlKCJjb2RlL3Bsb3RhX3NvbHVjb2VzX2hjbHVzdC5SIikpCgp0aGVtZV9zZXQodGhlbWVfcmVwb3J0KCkpCgprbml0cjo6b3B0c19jaHVuayRzZXQodGlkeSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoID0gNiwKICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQgPSA1LAogICAgICAgICAgICAgICAgICAgICAgZWNobyA9IFRSVUUpCnBhbGV0YSA9IGMoIiM0MDRFNEQiLAogICAgICAgICAgICIjOTJEQ0U1IiwKICAgICAgICAgICAiIzkzOEJBMSIsCiAgICAgICAgICAgIiMyRDMxNDIiLAogICAgICAgICAgICIjRjQ3NDNCIikKYGBgCgojIERhdGEgT3ZlcnZpZXcKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmltcG9ydF9kYXRhKCJqYWtlX2d5bGxlbmhhYWwiKSAKZmlsbWVzIDwtIHJlYWRfaW1wb3J0ZWRfZGF0YSgpCmZpbG1lcyAlPiUgCiAgICBnbGltcHNlKCkKYGBgCgojIyBCaWxoZXRlcmlhCgoqIERhZG9zIGRlIGJpbGhldGVyaWEgc2UgcmVmZXJlbSBhbyBhcnJlY2FkYW1lbnRvIGRlbnRybyBkb3MgRXN0YWRvcyBVbmlkb3MuCgpgYGB7cn0KcCA8LSBmaWxtZXMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIAogICAgICAgICAgICAgICB5ID0gYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQmlsaGV0ZXJpYToiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlsaGV0ZXJpYSwibSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5Bbm86Iixhbm8pKSkgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGNvbG9yID0gcGFsZXRhWzFdKSArCiAgICBsYWJzKHkgPSAiQmlsaGV0ZXJpYSIsIHggPSAiQW5vIGRlIGxhbsOnYW1lbnRvIikKCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRikKYGBgCgoqIEVudHJlIG9zIGZpbG1lcyBlbSBxdWUgSmFrZSBhdHVvdSB1bSBmb2dlIGFvcyBvdXRyb3MgZW0gdGVybW9zIGRlIGZhdHVyYW1lbnRvLCBvIGZpbG1lICAqKiJUaGUgRGF5IEFmdGVyIFRvbW9ycm93IioqIGxhbsOnYWRvIGVtIDIwMDQuCgoqIMOJIHBvc3PDrXZlbCBwZXJjZWJlciB1bWEgdGVuZMOqbmNpYSBkZSBxdWVkYSBubyBmYXR1cmFtZW50byBkb3MgZmlsbWVzIGVtIHF1ZSBKYWtlIGF0dW91IGFww7NzIDIwMTMuCgpgYGB7cn0KZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGJpbGhldGVyaWEpKSArIAogICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHk9KC4uY291bnQuLikvc3VtKC4uY291bnQuLikpLGJpbndpZHRoID0gMTAsIGJvdW5kYXJ5ID0gMCwgCiAgICAgICAgICAgICAgICAgICBmaWxsID0gImdyZXkiLCBjb2xvciA9ICJibGFjayIpICsgCiAgICBnZW9tX3J1ZyhzaXplID0gLjUpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsMjAwLDIwKSkgKwogICAgbGFicyh5ID0gIkZyZXF1w6puY2lhIFJlbGF0aXZhIiwgeCA9ICJCaWxoZXRlcmlhIikKCmBgYAoKKiBWZW1vcyBjbGFyYW1lbnRlIGEgZGlzcGFyaWRhZGUgZW50cmUgKioiVGhlIERheSBBZnRlciBUb21vcnJvdyIqKiAgZSBvcyBvdXRyb3MgZmlsbWVzLgoKKiBOZW5odW0gdmFsb3IgZm9yYSBkbyBkb23DrW5pbyBkZSB2YWxvcmVzIGVzcGVyYWRvLCBlLmcuIHZhbG9yZXMgbmVnYXRpdm9zLgoKYGBge3J9CnAgPC0gZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9ICIiLAogICAgICAgICAgICAgICB5ID0gYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgbGFiZWwgPSBmaWxtZSwKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQmlsaGV0ZXJpYToiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlsaGV0ZXJpYSwibSIpKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjA1LCBhbHBoYSA9IC4zLCBzaXplID0gMykgKyAKICAgIGxhYnMoeCA9ICIiLCB5PSJCaWxoZXRlcmlhIikKCmdncGxvdGx5KHAsIHRvb2x0aXA9InRleHQiKSAlPiUgCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiogU2VwYXJhciBvcyBmaWxtZXMgZW50cmUgb3MgZGUgYmlsaGV0ZXJpYSBhYmFpeG8gZSBhY2ltYSBkZSA1MCBtaWxow7VlcyBwYXJlY2UgdW1hIGFib3JkYWdlbSByYXpvw6F2ZWwuCgoqICoqIlRoZSBEYXkgQWZ0ZXIgVG9tb3Jyb3ciKiogYXBhcmVudGEgZm9ybWFyIHVtIGV4w6lyY2l0byBkZSB1bSBmaWxtZSBzw7MuIE8gcXVlIG5vcyBkYXJpYSAzIGdydXBvcy4gCgojIyBBdmFsaWHDp8OjbwoKYGBge3J9CnAgPC0gZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGFubywgCiAgICAgICAgICAgICAgIHkgPSBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIkZpbG1lOiIsZmlsbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5BdmFsaWHDp8OjbzoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhbGlhY2FvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQW5vOiIsYW5vKSkpICsgCiAgICBnZW9tX3BvaW50KHNpemUgPSA0LCBjb2xvciA9IHBhbGV0YVsxXSkgICsKICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEwMCkpICsKICAgIGxhYnMoeSA9ICJBdmFsaWHDp8OjbyBSVCIsIHggPSAiQW5vIGRlIGxhbsOnYW1lbnRvIikKCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRikKYGBgCgoqIEVudHJlIDIwMDUgZSAyMDEwIEpha2UgcGFydGljaXBvdSBkZSB1bWEgc8OpcmllIGRlIGZpbG1lcyBlbSBwYXJ0aWN1bGFyIHF1ZSBuw6NvIGFncmFkb3Ugb3MgY3LDrXRpY29zIAoqIE7Do28gYXBhcmVudGEgaGF2ZXIgdW1hIHRlbmTDqm5jaWEgcGFydGljdWxhcm1lbnRlIGNsYXJhIGVtIHJhesOjbyBkbyBhbm8gZGUgbGFuw6dhbWVudG8uIAoKYGBge3J9CmZpbG1lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSBhdmFsaWFjYW8pKSArIAogICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHk9KC4uY291bnQuLikvc3VtKC4uY291bnQuLikpLGJpbndpZHRoID0gMTAsIGJvdW5kYXJ5ID0gMCwgCiAgICAgICAgICAgICAgICAgICBmaWxsID0gcGFsZXRhWzNdLCBjb2xvciA9ICJibGFjayIpICsgCiAgICBnZW9tX3J1ZyhzaXplID0gLjUpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsMTAwLDEwKSkgKwogICAgbGFicyh5ID0gIkZyZXF1w6puY2lhIFJlbGF0aXZhIiwgeCA9ICJBdmFsaWHDp8OjbyBSVCIpCgpgYGAKCiogw4kgcG9zc8OtdmVsIHBlcmNlYmVyIHVtYSBxdWFudGlkYWRlIGNvbnNpZGVyw6F2ZWwgZGUgZmlsbWVzIGNvbSBub3RhcyBhY2ltYSBkZSA4MC4KCiogTmVuaHVtIHZhbG9yIGZvcmEgZG8gZG9tw61uaW8gZGUgdmFsb3JlcyBlc3BlcmFkbywgZS5nLiB2YWxvcmVzIG5lZ2F0aXZvcy4KCgpgYGB7cn0KcCA8LSBmaWxtZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gIiIsCiAgICAgICAgICAgICAgIHkgPSBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgKICAgICAgICAgICAgICAgICAgICAiRmlsbWU6IixmaWxtZSwKICAgICAgICAgICAgICAgICAgICAiXG5BdmFsaWHDp8OjbzoiLGF2YWxpYWNhbykpKSArIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMDUsIGFscGhhID0gLjMsIHNpemUgPSAzKSArIAogICAgbGFicyh4ID0gIiIsIHk9IkF2YWxpYcOnw6NvIFJUIikKCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpICU+JSAKICAgIGxheW91dChhdXRvc2l6ZSA9IEYpCgpgYGAKCiogSW50dWl0aXZhbWVudGUgdHLDqnMgZ3J1cG9zIHN1cmdlbToKICAgICogT3MgZmlsbWVzIGNvbSBhdmFsaWHDp8OjbyBhY2ltYSBkZSA4MAogICAgKiBPcyBmaWxtZXMgY29tIGF2YWxpYcOnw6NvIGVudHJlIDU1IGUgNzAgCiAgICAqIE9zIGZpbG1lcyBjb20gYXZhbGlhw6fDo28gYWJhaXhvIGRlIDU1Cgo8YnI+CgoqKioKCjxicj4KCiMgQWdydXBhbWVudG8gaGllcsOhcnF1aWNvCgo8YnI+Cjxicj4KCiMjIFVtYSBkaW1lbnPDo28KCjxicj4KCiMjIyBCaWxoZXRlcmlhIAoKYGBge3J9CmFncnVwYW1lbnRvX2ggPSBmaWxtZXMgJT4lIAogICAgbXV0YXRlKG5vbWUgPSBwYXN0ZTAoZmlsbWUsICIgKGJpbD0iLCBiaWxoZXRlcmlhLCAiKSIpKSAlPiUgCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgY29sdW1uX3RvX3Jvd25hbWVzKCJmaWxtZSIpICU+JSAKICAgIHNlbGVjdChiaWxoZXRlcmlhKSAlPiUKICAgIGRpc3QobWV0aG9kID0gImV1Y2xpZGlhbiIpICU+JSAKICAgIGhjbHVzdChtZXRob2QgPSAiY2VudHJvaWQiKQoKZ2dkZW5kcm9ncmFtKGFncnVwYW1lbnRvX2gsIHJvdGF0ZSA9IFQsIHNpemUgPSAyLCB0aGVtZV9kZW5kcm8gPSBGKSArCiAgICBsYWJzKHkgPSAiRGlzc2ltaWxhcmlkYWRlIiwgeCA9ICIiLCB0aXRsZSA9ICJEZW5kcm9ncmFtYSIpICsKICAgIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBjKDIwLDMwKSwgY29sb3I9YygiNCBncnVwb3MiLCIzIGdydXBvcyIpKSkgKwogICAgc2NhbGVfY29sb3VyX21hbnVhbChuYW1lPSIjR3J1cG9zIiwKICAgIHZhbHVlcz1jKCIjNTZCNEU5IiwgIiNGRjk5OTkiKSkKYGBgCgoqIEVtIHRlcm1vcyBkZSBEZW5kb2dyYW1hIGEgZGl2aXPDo28gZW0gcXVhdHJvIGdydXBvcyBhc3NpbSBjb21vIGEgZGl2aXPDo28gZW0gMyBncnVwb3MgcGFyZWNlbSBzZXIgYXByb3ByaWFkYXMsIGRhZG8gcXVlIG8gYXVtZW50byBkZSBkaXNzaW1pbGFyaWRhZGUgZGUgNCBwYXJhIDMgZ3J1cG9zIG7Do28gYXBhcmVudGFyIHNlciBzdWJzdGFuY2lhbC4KKiAgQ29ydGUgZmVpdG8gcGFyYSA0IGdydXBvcwoKYGBge3J9CmF0cmlidWljb2VzID0gZ2V0X2dydXBvcyhhZ3J1cGFtZW50b19oLCBudW1fZ3J1cG9zID0gMTo2KQoKYXRyaWJ1aWNvZXMgPSBhdHJpYnVpY29lcyAlPiUgCiAgICBsZWZ0X2pvaW4oZmlsbWVzLCBieSA9IGMoImxhYmVsIiA9ICJmaWxtZSIpKQoKYXRyaWJ1aWNvZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gIkZpbG1lcyIsIHkgPSBiaWxoZXRlcmlhLCBjb2xvdXIgPSBncnVwbykpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wMiwgaGVpZ2h0ID0gMCwgc2l6ZSA9IDEuNiwgYWxwaGEgPSAuNikgKyAKICAgIGZhY2V0X3dyYXAofiBwYXN0ZShrLCAiIGdydXBvcyIpKSArIAogICAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgICBsYWJzKHkgPSAiQmlsaGV0ZXJpYSAobWlsaMO1ZXMpIiwgeCA9ICIiLCB0aXRsZSA9ICJBZ3J1cGFtZW50byBwb3IgQmlsaGV0ZXJpYSIpCgpgYGAKCiogQSBkaXZpc8OjbyBlbSA0IGdydXBvcyBwYXJlY2Ugc2VyIG1haXMgYXByb3ByaWFkYSBxdWUgYSBkaXZpc8OjbyBlbSAzIGdydXBvcy4KICAgICogTyBjbHVzdGVyIGRlIGZpbG1lcyBuYSBiYXNlIGRvIGdyw6FmaWNvIGFwYXJlbnRhIGV4aWdpciB1bSBncnVwbyBwcsOzcHJpbyAoTmEgZGl2aXPDo28gZW0gNCBncnVwb3MgbyBncnVwbyBtZW5jaW9uYWRvIHNlcmlhIG8gZ3J1cG8gMSkuIAoKYGBge3J9CmtfZXNjb2xoaWRvID0gNAoKbSA8LSBsaXN0KGwgPSAyMjApCgpwIDwtYXRyaWJ1aWNvZXMgJT4lIAogICAgZmlsdGVyKGsgPT0ga19lc2NvbGhpZG8pICU+JSAKICAgIGdncGxvdChhZXMoeCA9IHJlb3JkZXIobGFiZWwsIGJpbGhldGVyaWEpLAogICAgICAgICAgICAgICB5ID0gYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgY29sb3VyID0gZ3J1cG8sCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgKICAgICAgICAgICAgICAgICAgICAiRmlsbWU6IiwgcmVvcmRlcihsYWJlbCwgYmlsaGV0ZXJpYSksCiAgICAgICAgICAgICAgICAgICAgIlxuQXZhbGlhw6fDo286IiwgYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgICAgICAiXG5HcnVwbzoiLCBncnVwbykpKSArIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMDIsIGhlaWdodCA9IDAsIHNpemUgPSAzLCBhbHBoYSA9IC42KSArIAogICAgZmFjZXRfd3JhcCh+IHBhc3RlKGssICIgZ3J1cG9zIikpICsgCiAgICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsgCiAgICBsYWJzKHggPSAiIiwgeSA9ICJBdmFsaWHDp8OjbyBSVCIpICsgCiAgICBjb29yZF9mbGlwKCkKCmdncGxvdGx5KHAsdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGLCBtYXJnaW4gPSBtKQoKYGBgCgoqICoqVGhlIERheSBBZnRlciBUb21vcnJvdyoqIGV4aWdpdSB1bSBncnVwbyBwYXJhIHNpLCBjb21vIGVyYSBlc3BlcmFkby4KCjxicj4KCiMjIyBBdmFsaWHDp8OjbyAKCmBgYHtyfQphZ3J1cGFtZW50b19oID0gZmlsbWVzICU+JSAKICAgIG11dGF0ZShub21lID0gcGFzdGUwKGZpbG1lLCAiIChhdj0iLCBhdmFsaWFjYW8sICIpIikpICU+JSAKICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgICBjb2x1bW5fdG9fcm93bmFtZXMoImZpbG1lIikgJT4lIAogICAgc2VsZWN0KGF2YWxpYWNhbykgJT4lCiAgICBkaXN0KG1ldGhvZCA9ICJldWNsaWRpYW4iKSAlPiUgCiAgICBoY2x1c3QobWV0aG9kID0gIndhcmQuRCIpCgpnZ2RlbmRyb2dyYW0oYWdydXBhbWVudG9faCwgcm90YXRlID0gVCwgc2l6ZSA9IDIsIHRoZW1lX2RlbmRybyA9IEYpICsKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikgKwogICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDMwKSxjb2xvcj0icmVkIikKYGBgCgoqIEVtIHRlcm1vcyBkZSBEZW5kb2dyYW1hIGEgKipkaXZpc8OjbyBlbSB0csOqcyBncnVwb3MgcGFyZWNlIHNlciBhIG1haXMgYXByb3ByaWFkYSoqLCBkYWRvIHF1ZSBvIGF1bWVudG8gZGEgZGlzc2ltaWxhcmlkYWRlIHBhc3NhIGEgc2VyIHN1YnN0YW5jaWFsIHF1YW5kbyBwYXNzYW1vcyBkZSAzIHBhcmEgMiBncnVwb3MuCgpgYGB7cn0KYXRyaWJ1aWNvZXMgPSBnZXRfZ3J1cG9zKGFncnVwYW1lbnRvX2gsIG51bV9ncnVwb3MgPSAxOjYpCgphdHJpYnVpY29lcyA9IGF0cmlidWljb2VzICU+JSAKICAgIGxlZnRfam9pbihmaWxtZXMsIGJ5ID0gYygibGFiZWwiID0gImZpbG1lIikpCgphdHJpYnVpY29lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSAiRmlsbWVzIiwgeSA9IGF2YWxpYWNhbywgY29sb3VyID0gZ3J1cG8pKSArIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMDIsIGhlaWdodCA9IDAsIHNpemUgPSAxLjYsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogICAgbGFicyh5ID0gIkF2YWxpYcOnw6NvIFJUIiwgeCA9ICIiLCB0aXRsZSA9ICJBZ3J1cGFtZW50byBwb3IgQXZhbGlhw6fDo28iKQoKYGBgCgoqIFZpc3VhbG1lbnRlIGEgZGl2aXPDo28gZW0gdHLDqnMgZ3J1cG9zIHBhcmVjZSBkZSBmYXRvIHNlciBhcHJvcHJpYWRhLCBvIHF1ZSBlc3TDoSBlbSBhY29yZG8gY29tIG8gZGVuZHJvZ3JhbWEuCgpgYGB7cn0Ka19lc2NvbGhpZG8gPSAzCgptIDwtIGxpc3QobCA9IDIyMCkKCnAgPC1hdHJpYnVpY29lcyAlPiUgCiAgICBmaWx0ZXIoayA9PSBrX2VzY29saGlkbykgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihsYWJlbCwgYXZhbGlhY2FvKSwKICAgICAgICAgICAgICAgeSA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgY29sb3VyID0gZ3J1cG8sCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgKICAgICAgICAgICAgICAgICAgICAiRmlsbWU6IiwgcmVvcmRlcihsYWJlbCwgYXZhbGlhY2FvKSwKICAgICAgICAgICAgICAgICAgICAiXG5BdmFsaWHDp8OjbzoiLCBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgICAgICAgIlxuR3J1cG86IiwgZ3J1cG8pKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjAyLCBoZWlnaHQgPSAwLCBzaXplID0gMywgYWxwaGEgPSAuNikgKyAKICAgIGZhY2V0X3dyYXAofiBwYXN0ZShrLCAiIGdydXBvcyIpKSArIAogICAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArIAogICAgbGFicyh4ID0gIiIsIHkgPSAiQXZhbGlhw6fDo28gUlQiKSArIAogICAgY29vcmRfZmxpcCgpCgpnZ3Bsb3RseShwLHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRiwgbWFyZ2luID0gbSkKCmBgYAoKKiBEaXNjdXRpdmVsbWVudGUsICoqUHJpbmNlIG9mIFBlcnNpYTogVGhlIFNhbmRzIG9mIFRpbWUqKiBwb2RlcmlhIGV4aWdpciB1bSBncnVwbyBwYXJhIHNpIHByw7NwcmlvLgoKPGJyPgoKIyMgRHVhcyBkaW1lbnPDtWVzCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KYWdydXBhbWVudG9faF8yZCA9IGZpbG1lcyAlPiUKICAgbXV0YXRlKGJpbGhldGVyaWEgPSBsb2cxMChiaWxoZXRlcmlhKSkgJT4lCiAgIG11dGF0ZV9hdCh2YXJzKCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpLCBmdW5zKHNjYWxlKSkgJT4lCiAgIGNvbHVtbl90b19yb3duYW1lcygiZmlsbWUiKSAlPiUKICAgc2VsZWN0KCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpICU+JQogICBkaXN0KG1ldGhvZCA9ICJldWNsaWRlYW4iKSAlPiUKICAgaGNsdXN0KG1ldGhvZCA9ICJ3YXJkLkQiKQoKZ2dkZW5kcm9ncmFtKGFncnVwYW1lbnRvX2hfMmQsIHJvdGF0ZSA9IFRSVUUsIHRoZW1lX2RlbmRybyA9IEYpICsKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikgKwogICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDQpLGNvbG9yPSJyZWQiKQoKYGBgCgoqIFBhc3NhciBkZSA0IHBhcmEgMyBncnVwb3MgcmVwcmVzZW50YSBwb3VjYSB2YXJpYcOnw6NvIGVtIHRlcm1vcyBkZSBkaXNzaW1pbGFyaWRhZGUKKiBQYXNzYXIgZGUgMyBwYXJhIDIgZ3J1cG9zIGFwcmVzZW50YSB1bSBhdW1lbnRvIHJlbGF0aXZvIGRlIGRpc3NpbWlsYXJpZGFkZSBzdWJzdGFuY2lhbCwgcG9ydGFudG8gMyBvdSA0IGdydXBvcyBwYXJlY2Ugc2VyIHVtYSBib2EgZXNjb2xoYS4KCmBgYHtyfQpmaWxtZXMyIDwtIGZpbG1lcyAlPiUKICAgIG11dGF0ZShiaWxoZXRlcmlhID0gbG9nMTAoYmlsaGV0ZXJpYSkpCgpwbG90YV9oY2x1c3RzXzJkKGFncnVwYW1lbnRvX2hfMmQsCiAgICAgICAgICAgICAgICBmaWxtZXMyLAogICAgICAgICAgICAgICAgYygiYXZhbGlhY2FvIiwgImJpbGhldGVyaWEiKSwKICAgICAgICAgICAgICAgIGxpbmthZ2VfbWV0aG9kID0gIndhcmQuRCIsIAogICAgICAgICAgICAgICAga3MgPSAxOjYsCiAgICAgICAgICAgICAgICBwYWxldHRlID0gIkRhcmsyIikgKyAKICAgIHNjYWxlX3lfbG9nMTAoKSArCiAgICBsYWJzKHkgPSAiQmlsaGV0ZXJpYSIsIHggPSAiQXZhbGlhw6fDo28iLCB0aXRsZSA9ICJBZ3J1cGFtZW50byBjb20gRHVhcyBEaW1lbnPDtWVzIikKYGBgCgoqIEEgZXNjb2xoYSBwb3IgNCBncnVwb3MgcGFyZWNlIHNlciBhcHJvcHJpYWRhLCBwb3IgcmVmbGV0aXIgdGFudG8gcXVlc3TDtWVzIGRlIGJpbGhldGVyaWEgY29tbyBkZSBhdmFsaWHDp8Ojby4gRW0gYWNvcmRvIGNvbSBvIHF1ZSBpbnRlcnByZXRhbW9zIG5vIGRlbmRyb2dyYW1hICoqb3B0YXJlbW9zIHBvciA0IGdydXBvcy4qKiAKCmBgYHtyfQphdHJpYnVpY29lcyA9IGdldF9ncnVwb3MoYWdydXBhbWVudG9faF8yZCwgbnVtX2dydXBvcyA9IDE6NikKCmF0cmlidWljb2VzID0gYXRyaWJ1aWNvZXMgJT4lIAogICAgZmlsdGVyKGsgPT0gNCkgJT4lCiAgICBtdXRhdGUoZmlsbWUgPSBsYWJlbCkgJT4lIAogICAgbGVmdF9qb2luKGZpbG1lcywgYnkgPSAiZmlsbWUiKQoKcCA8LSBhdHJpYnVpY29lcyAlPiUKICAgIGdncGxvdChhZXMoeCA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgeSA9IGJpbGhldGVyaWEsCiAgICAgICAgICAgICAgIGNvbG91ciA9IGdydXBvLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoCiAgICAgICAgICAgICAgICAgICAgIkZpbG1lOiIsIGZpbG1lLAogICAgICAgICAgICAgICAgICAgICJcbkJpbGhldGVyaWE6IiwgYmlsaGV0ZXJpYSwibVxuIiwKICAgICAgICAgICAgICAgICAgICAiQXZhbGlhw6fDo286IiwgYXZhbGlhY2FvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wMiwgaGVpZ2h0ID0gMCwgc2l6ZSA9IDMsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogICAgc2NhbGVfeV9sb2cxMCgpICsKICAgIGxhYnMoeSA9ICJCaWxoZXRlcmlhIiwgeCA9ICJBdmFsaWHDp8OjbyBSVCIpCgoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiogJFxjb2xvcntncmVlbn17XHRleHR7R3J1cG8gMSAoT2RkYmFsbCk6fX0kIEZpbG1lcyBlbSBnZXJhbCBfYmVtIHJlY2ViaWRvcyBwZWxhIGNyw610aWNhIHBvcsOpbSBtYWwgcmVjZWJpZG9zIHBlbG8gcMO6YmxpY29fLCBvIHF1ZSBzZSByZWZsZXRlIG5vIHNldSBiYWl4byBhcnJlY2FkYW1lbnRvLgogICAgKiAqKlN0cm9uZ2VyKio6IEZpbG1lIGJpb2dyw6FmaWNvIHNvYnJlICdKZWZmIEJhdW1hbicsIHbDrXRpbWEgZG8gYXRlbnRhZG8gZGUgQm9zdG9uIHF1ZSBwZXJkZXUgYW1iYXMgYXMgcGVybmFzIG5hIGV4cGxvc8Ojby4gTyBmaWxtZSBmb2kgbXVpdG8gYmVtIHJlY2ViaWRvIHBlbG9zIGNyw610aWNvcyBxdWUgbyBlbG9naWFyYW0gcG9yIHNlciBiZW0gZXhlY3V0YWRvLCBjb21vdmVudGUgZSBwb3IgZm9jYXIgbnVtYSBoaXN0w7NyaWEgZGUgc3VwZXJhw6fDo28gYW8gaW52w6lzIGRlIHVzYXIgYSB0cmFnw6lkaWEgcGFyYSBhbGltZW50YXIgYSBwYXJhbsOzaWEgZW0gY2ltYSBkbyB0ZXJyb3Jpc21vLiBPIGZpbG1lIHBvcsOpbSBmb2kgdW0gZnJhY2Fzc28gZW0gdGVybW9zIGRlIGJpbGhldGVyaWEuCgo8YnIvPgoKKiAkXGNvbG9yeyNDRjUzMDB9e1x0ZXh0e0dydXBvIDIgKFNlc3PDo28gZGEgVGFyZGUpOn19JCBGaWxtZXMgZW0gZ2VyYWwgX27Do28gdMOjbyBiZW0gcmVjZWJpZG9zIHBlbGEgY3LDrXRpY2EgZSBtYWlzIGZvcm11bGFpY29zXy4gRW0gdGVybW9zIGRlIGJpbGhldGVyaWEgYSBtYWlvciBwYXJ0ZSBkZWxlcyBmb2kgYmFpeGEgbWFzIG8gZmlsbWUgc2UgcGFnb3UsIGNvbSBkdWFzIGV4Y2XDp8O1ZXMgcXVlIGFycmVjYWRhcmFtIG1lbGhvciAoJ1ByaW5jZSBvZiBQZXJzaWE6IFRoZSBTYW5kcyBvZiBUaW1lJyBlICdUaGUgRGF5IEFmdGVyIFRvbW9ycm93JykuIFBhcmEgZXNzZSBncnVwbyBleGlzdGUgdW1hIGN1cmlvc2lkYWRlLCBwYXJhIGEgX21haW9yaWFfIGRvcyBmaWxtZXMgZGVzc2UgZ3J1cG8gcXVhbnRvIG1haW9yIG8gYXJyZWNhZGFtZW50byBtZW5vciBhIGF2YWxpYcOnw6NvLgogICAgKiAqKlByaW5jZSBvZiBQZXJzaWE6IFRoZSBTYW5kcyBvZiBUaW1lKio6IEJhc2VhZG8gbm8gam9nbyBkZSBtZXNtbyBub21lLCBlc3RlIGpvZ28gdW1hIHJlZmVyw6puY2lhIGVtIHF1YWxpZGFkZSBlIGlub3Zhw6fDo28uIE8gZmlsbWUgcmVzdWx0b3UgZW0gY29tZW50w6FyaW9zIGRlY2VwY2lvbmFkb3MgdGFudG8gZGUgY3LDrXRpY29zIGUgZsOjcyBxdWUgbsOjbyBmYWxoYXJhbSBlbSBjb250cmlidWlyIHBybyBhcnJlY2FkYW1lbnRvIGRvIGZpbG1lLgoKPGJyLz4KCiogJFxjb2xvcntwdXJwbGV9e1x0ZXh0e0dydXBvIDMgKERlbW9saXRpb24gb2YgYSBidWRnZXQpOn19JCBGaWxtZXMgZW0gZ2VyYWwgX21hbCByZWNlYmlkb3MgcGVsYSBjcsOtdGljYSBlIHBlbG8gcMO6YmxpY29fLCBvIHF1ZSBzZSByZWZsZXRlIG5vIHNldSBiYWl4byBhcnJlY2FkYW1lbnRvIGUgYXZhbGlhw6fDtWVzLiAKICAgICogKipEZW1vbGl0aW9uKio6IE5lc3RlIGZpbG1lIEpha2UgYXR1YSBubyBwYXBlbCBkZSB1bSBob21lbSBxdWUgdm9sdGEgYW8gdHJhYmFsaG8gZGVwb2lzIGRlIHBlcmRlciBhIGVzcG9zYSBlIGVuY29udHJhIGNvbnRhdG8gaHVtYW5vIGVtIHVtYSBhdGVuZGVudGUgZGUgdGVsZW1hcmtldGluZyBhbyByZWNsYW1hciBkZSB1bWEgdmVuZGluZyBtYWNoaW5lLiBPIGZpbG1lIGZvaSB1bSBmcmFjYXNzbyBlbSB0ZXJtb3MgZGUgYXJyZWNhZGFtZW50byBhc3NpbSBjb21vIGVtIHRlcm1vcyBkZSBjcsOtdGljYS4gTyBmaWxtZSB0ZXZlIHNldSBzY3JpcHQgYXBvbnRhZG8gY29tbyBncmFuZGUgcHJvYmxlbWEsIGVzc2UgZm9pIGRlc2NyaXRvIGNvbW8gJ3RlbnRhbmRvIGFmZXRhciBwcm9mdW5kaWRhZGUnIGUgYW50aS1jYXJpc23DoXRpY28uCiAgICAKPGJyLz4KCiogJFxjb2xvcnttYWdlbnRhfXtcdGV4dHtHcnVwbyA0IChCcm9rZWJhY2sgTW91bnRhaW4pOn19JCBGaWxtZXMgX2FjbGFtYWRvcyBwZWxhIGNyw610aWNhXyBlIGRlIGZhdHVyYW1lbnRvIGRlY2VudGUgb3UgZGUgIHN1Y2Vzc28sIG9zIGZpbG1lcyBkZXNlIGdydXBvIHPDo28gZGUgdG9tIG1haXMgc8OpcmlvIHRyYXRhbmRvIGRlIGFzc3VudG9zIHNpZ25pZmljYXRpdm9zIGUgZ2VyYWRvcmVzIGRlIGNvbnRyb3bDqXJzaWEgKGFzc2Fzc2luYXRvcyBlbSBzw6lyaWUgdmVyw61kaWNvcywgbsOjbyBoZXRlcm9zc2V4dWFsaWRhZGUsIHRlcnJvcmlzbW8uLiApLiAKICAgICogKipCcm9rZWJhY2sgTW91bnRhaW4qKjogUHJvdmF2ZWxtZW50ZSBhIG1lbGhvciBhdHVhw6fDo28gZGUgSmFrZSBHeWxsZW5oYWFsIGF0w6kgbyBtb21lbnRvLCBlc3NlIGZpbG1lIHJlbmRldSBhIEpha2UgdW1hIGluZGljYcOnw6NvIGFvIE9zY2FyIGUgbGV2YW50b3UgbXVpdGEgY29udHJvdsOpcnNpYSBwb3IgY29udGVyIHVtYSBjZW5hIGRlIHNleG8gZW50cmUgcGVzc29hcyBkbyBtZXNtbyBzZXhvLiBBIEFjYWRlbWlhIChyZXNwb25zw6F2ZWwgcG9yIGVzY29saGVyIG9zIHZlbmNlZG9yZXMgZG8gT3NjYXIpIGZvaSBhY3VzYWRhIGRlIGhvbW9mb2JpYSBwb3IgbsOjbyBlc2NvbGhlciBlc3NlIGZpbG1lIGNvbW8gbyBnYW5oYWRvciBkZSBNZWxob3IgRm90b2dyYWZpYSwgYWluZGEgYXNzaW0gQnJva2ViYWNrIE1vdW50YWluIGdhbmhvdSBtYWlzIGdhbmhvdSAxNDEgcHLDqm1pb3MgZSAxMjggbm9taW5hw6fDtWVzIGRlIGFjb3JkbyBjb20gbyBJTURCLiBPIGZpbG1lIGZvaSBjb25zaWRlcmFkbyB1bSBzdWNlc3NvIHRhbnRvIGVtIGZhdHVyYW1lbnRvIGNvbW8gZW0gYXZhbGlhw6fDo28uCiAgICAK